home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / tools / indent.lha / indent / comment.c < prev    next >
C/C++ Source or Header  |  1992-07-06  |  17KB  |  466 lines

  1. /*
  2.  * Copyright (c) 1985 Sun Microsystems, Inc.
  3.  * Copyright (c) 1980 The Regents of the University of California.
  4.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted
  8.  * provided that the above copyright notice and this paragraph are
  9.  * duplicated in all such forms and that any documentation,
  10.  * advertising materials, and other materials related to such
  11.  * distribution and use acknowledge that the software was developed
  12.  * by the University of California, Berkeley, the University of Illinois,
  13.  * Urbana, and Sun Microsystems, Inc.  The name of either University
  14.  * or Sun Microsystems may not be used to endorse or promote products
  15.  * derived from this software without specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  17.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  18.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. # ifndef OS2
  23.     static char sccsid[] = "@(#)comment.c    6.0 (Berkeley) 92/06/15";
  24. # endif
  25. #endif                          /* not lint */
  26.  
  27. /*
  28.  * NAME:
  29.  *    pr_comment
  30.  *
  31.  * FUNCTION:
  32.  *    This routine takes care of scanning and printing comments.
  33.  *
  34.  * ALGORITHM:
  35.  *    1) Decide where the comment should be aligned, and if lines should
  36.  *       be broken.
  37.  *    2) If lines should not be broken and filled, just copy up to end of
  38.  *       comment.
  39.  *    3) If lines should be filled, then scan thru input_buffer copying
  40.  *       characters to com_buf.  Remember where the last blank, tab, or
  41.  *       newline was.  When line is filled, print up to last blank and
  42.  *       continue copying.
  43.  *
  44.  * HISTORY:
  45.  *    November 1976    D A Willcox of CAC    Initial coding
  46.  *    12/6/76        D A Willcox of CAC    Modification to handle
  47.  *                        UNIX-style comments
  48.  *
  49.  */
  50.  
  51. /*
  52.  * this routine processes comments.  It makes an attempt to keep comments from
  53.  * going over the max line length.  If a line is too long, it moves everything
  54.  * from the last blank to the next comment line.  Blanks and tabs from the
  55.  * beginning of the input line are removed
  56.  */
  57.  
  58.  
  59. #include "globals.h"
  60.  
  61. #ifdef OS2
  62. #include <malloc.h>
  63. #endif
  64.  
  65. #ifdef ANSIC
  66. void pr_comment(void)
  67. #else
  68. pr_comment()
  69. #endif
  70. {
  71.     int now_col;                /* column we are in now */
  72.     int adj_max_col;            /* Adjusted max_col for when we decide to spill
  73.                                    comments over the right margin */
  74.     char *last_bl;              /* points to the last blank in the output
  75.                                    buffer */
  76.     char *t_ptr;                /* used for moving string */
  77.     int unix_comment;           /* tri-state variable used to decide if it is a
  78.                                    unix-style comment. 0 means only blanks
  79.                                    since /*, 1 means regular style comment, 2
  80.                                    means unix style comment */
  81.     int break_delim = comment_delimiter_on_blankline;
  82.     int l_just_saw_decl = ps.just_saw_decl;
  83.  
  84.     /*
  85.        int         ps.last_nl = 0;    /* true iff the last significant thing weve
  86.        seen is a newline
  87.     */
  88.     int one_liner = 1;          /* true iff this comment is a one-liner */
  89.  
  90.     adj_max_col = max_col;
  91.     ps.just_saw_decl = 0;
  92.     last_bl = 0;                /* no blanks found so far */
  93.     ps.box_com = false;         /* at first, assume that we are not in a boxed
  94.                                    comment or some other comment that should
  95.                                    not be touched */
  96.     ++ps.out_coms;              /* keep track of number of comments */
  97.     unix_comment = 1;           /* set flag to let us figure out if there is a
  98.                                    unix-style comment ** DISABLED: use 0 to
  99.                                    reenable this hack! */
  100.  
  101.     /* Figure where to align and how to treat the comment */
  102.  
  103.     if (ps.col_1 && !format_col1_comments)
  104.     {                           /* if comment starts in column 1 it should not
  105.                                    be touched */
  106.         ps.box_com = true;
  107.         ps.com_col = 1;
  108.     }
  109.     else
  110.     {
  111.         if (*buf_ptr == '-' || *buf_ptr == '*')
  112.         {
  113.             ps.box_com = true;  /* a comment with a '-' or '*' immediately
  114.                                    after the /* is assumed to be a boxed
  115.                                    comment */
  116.             break_delim = 0;
  117.         }
  118.         if ( /* ps.bl_line && */ (s_lab == e_lab) && (s_code == e_code))
  119.         {
  120.             /* klg: check only if this line is blank */
  121.             /*
  122.                If this (*and previous lines are*) blank, dont put comment way
  123.                out at left
  124.             */
  125.             ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
  126.             adj_max_col = block_comment_max_col;
  127.             if (ps.com_col <= 1)
  128.                 ps.com_col = 1 + !format_col1_comments;
  129.         }
  130.         else
  131.         {
  132.             register target_col;
  133.  
  134.             break_delim = 0;
  135.             if (s_code != e_code)
  136.                 target_col = count_spaces(compute_code_target(), s_code);
  137.             else
  138.             {
  139.                 target_col = 1;
  140.                 if (s_lab != e_lab)
  141.                     target_col = count_spaces(compute_label_target(), s_lab);
  142.             }
  143.             ps.com_col = ps.decl_on_line || ps.ind_level == 0 ? ps.decl_com_ind : ps.com_ind;
  144.             if (ps.com_col < target_col)
  145.                 ps.com_col = target_col +
  146.                     (tabsize - ((target_col - 1) % tabsize)); /* JHT 22oct89 */
  147.             if (ps.com_col + 24 > adj_max_col)
  148.                 adj_max_col = ps.com_col + 24;
  149.         }
  150.     }
  151.     if (ps.box_com)
  152.     {
  153.         buf_ptr[-2] = 0;
  154.         ps.n_comment_delta = 1 - count_spaces(1, in_buffer);
  155.         buf_ptr[-2] = '/';
  156.     }
  157.     else
  158.     {
  159.         ps.n_comment_delta = 0;
  160.         while (*buf_ptr == ' ' || *buf_ptr == '\t')
  161.             buf_ptr++;
  162.     }
  163.     ps.comment_delta = 0;
  164.     *e_com++ = '/';             /* put '/*' into buffer */
  165.     if (ps.cc_comment)          /* (or '//') */
  166.         *e_com++ = '/';
  167.     else
  168.         *e_com++ = '*';
  169.     if (*buf_ptr != ' ' && !ps.box_com)
  170.         *e_com++ = ' ';
  171.  
  172.     *e_com = '\0';
  173.     if (troff)
  174.     {
  175.         now_col = 1;
  176.         adj_max_col = 80;
  177.     }
  178.     else
  179.         now_col = count_spaces(ps.com_col, s_com);  /* figure what column we
  180.                                                        would be in if we
  181.                                                        printed the comment now */
  182.  
  183.     /* Start to copy the comment */
  184.  
  185.     while (1)
  186.     {                           /* this loop will go until the comment is
  187.                                    copied */
  188.         if (*buf_ptr >= 040 && *buf_ptr != '*')
  189.             ps.last_nl = 0;
  190.         check_size(com);
  191.         switch (*buf_ptr)
  192.         {                       /* this checks for various spcl cases */
  193.         case 014:              /* check for a form feed */
  194.             if (!ps.box_com)
  195.             {                   /* in a text comment, break the line here */
  196.                 ps.use_ff = true;
  197.                 /* fix so dump_line uses a form feed */
  198.                 dump_line();
  199.                 last_bl = 0;
  200.                 *e_com++ = ' ';
  201.                 *e_com++ = '*';
  202.                 *e_com++ = ' ';
  203.                 while (*++buf_ptr == ' ' || *buf_ptr == '\t');
  204.             }
  205.             else
  206.             {
  207.                 if (++buf_ptr >= buf_end)
  208.                     fill_buffer();
  209.                 *e_com++ = 014;
  210.             }
  211.             break;
  212.  
  213.         case '\n':
  214.             if (ps.cc_comment)
  215.             {
  216.                 *e_com = '\0';
  217.                 dump_line();
  218.                 ps.cc_comment = 0;
  219.                 ps.just_saw_decl = l_just_saw_decl; /* ?? */
  220.                 if (++buf_ptr >= buf_end) /* eat '\n' */
  221.                     fill_buffer();
  222.                 ps.last_nl = 1; /* jrs 12 Mar 92 */
  223.                 return;
  224.             }
  225.             if (had_eof)
  226.             {                   /* check for unexpected eof */
  227.                 printf("Unterminated comment\n");
  228.                 *e_com = '\0';
  229.                 dump_line();
  230.                 return;
  231.             }
  232.             one_liner = 0;
  233.             if (ps.box_com || ps.last_nl)
  234.             {                   /* if this is a boxed comment, we dont ignore
  235.                                    the newline */
  236.                 if (s_com == e_com)
  237.                 {
  238.                     *e_com++ = ' ';
  239.                     *e_com++ = ' ';
  240.                 }
  241.                 *e_com = '\0';
  242.                 if (!ps.box_com && e_com - s_com > 3)
  243.                 {
  244.                     if (break_delim == 1 && s_com[0] == '/'
  245.                         && s_com[1] == '*' && s_com[2] == ' ')
  246.                     {
  247.                         char *t = e_com;
  248.  
  249.                         break_delim = 2;
  250.                         e_com = s_com + 2;
  251.                         *e_com = 0;
  252.                         if (blanklines_before_blockcomments)
  253.                             prefix_blankline_requested = 1;
  254.                         dump_line();
  255.                         e_com = t;
  256.                         s_com[0] = s_com[1] = s_com[2] = ' ';
  257.                     }
  258.                     dump_line();
  259.                     check_size(com);
  260.                     *e_com++ = ' ';
  261.                     *e_com++ = ' ';
  262.                 }
  263.                 dump_line();
  264.                 now_col = ps.com_col;
  265.             }
  266.             else
  267.             {
  268.                 ps.last_nl = 1;
  269.                 if (unix_comment != 1)
  270.                 {               /* we are not in unix_style comment */
  271.                     if (unix_comment == 0 && s_code == e_code)
  272.                     {
  273.                         /*
  274.                            if it is a UNIX-style comment, ignore the
  275.                            requirement that previous line be blank for
  276.                            unindention
  277.                         */
  278.                         ps.com_col = (ps.ind_level - ps.unindent_displace) * ps.ind_size + 1;
  279.                         if (ps.com_col <= 1)
  280.                             ps.com_col = 2;
  281.                     }
  282.                     unix_comment = 2; /* permanently remember that we are in
  283.                                          this type of comment */
  284.                     dump_line();
  285.                     ++line_no;
  286.                     now_col = ps.com_col;
  287.                     *e_com++ = ' ';
  288.                     /*
  289.                        fix so that the star at the start of the line will line
  290.                        up
  291.                     */
  292.                     do          /* flush leading white space */
  293.                         if (++buf_ptr >= buf_end)
  294.                             fill_buffer();
  295.                     while (*buf_ptr == ' ' || *buf_ptr == '\t');
  296.                     break;
  297.                 }
  298.                 if (*(e_com - 1) == ' ' || *(e_com - 1) == '\t')
  299.                     last_bl = e_com - 1;
  300.                 /*
  301.                    if there was a space at the end of the last line, remember
  302.                    where it was
  303.                 */
  304.                 else
  305.                 {               /* otherwise, insert one */
  306.                     last_bl = e_com;
  307.                     check_size(com);
  308.                     *e_com++ = ' ';
  309.                     ++now_col;
  310.                 }
  311.             }
  312.             ++line_no;          /* keep track of input line number */
  313.             if (!ps.box_com)
  314.             {
  315.                 int nstar = 1;
  316.  
  317.                 do
  318.                 {               /* flush any blanks and/or tabs at start of
  319.                                    next line */
  320.                     if (++buf_ptr >= buf_end)
  321.                         fill_buffer();
  322.                     if (*buf_ptr == '*' && --nstar >= 0)
  323.                     {
  324.                         if (++buf_ptr >= buf_end)
  325.                             fill_buffer();
  326.                         if (*buf_ptr == '/')
  327.                             goto end_of_comment;
  328.                     }
  329.                 } while (*buf_ptr == ' ' || *buf_ptr == '\t');
  330.             }
  331.             else if (++buf_ptr >= buf_end)
  332.                 fill_buffer();
  333.             break;              /* end of case for newline */
  334.  
  335.         case '*':              /* must check for possibility of being at end
  336.                                    of comment */
  337.             if (++buf_ptr >= buf_end) /* get to next char after * */
  338.                 fill_buffer();
  339.  
  340.             if (unix_comment == 0)  /* set flag to show we are not in
  341.                                        unix-style comment */
  342.                 unix_comment = 1;
  343.  
  344.             if (*buf_ptr == '/')
  345.             {                   /* it is the end!!! */
  346.         end_of_comment:
  347.                 if (++buf_ptr >= buf_end)
  348.                     fill_buffer();
  349.  
  350.                 if (*(e_com - 1) != ' ' && !ps.box_com)
  351.                 {               /* ensure blank before end */
  352.                     *e_com++ = ' ';
  353.                     ++now_col;
  354.                 }
  355.                 if (break_delim == 1 && !one_liner && s_com[0] == '/'
  356.                     && s_com[1] == '*' && s_com[2] == ' ')
  357.                 {
  358.                     char *t = e_com;
  359.  
  360.                     break_delim = 2;
  361.                     e_com = s_com + 2;
  362.                     *e_com = 0;
  363.                     if (blanklines_before_blockcomments)
  364.                         prefix_blankline_requested = 1;
  365.                     dump_line();
  366.                     e_com = t;
  367.                     s_com[0] = s_com[1] = s_com[2] = ' ';
  368.                 }
  369.                 if (break_delim == 2 && e_com > s_com + 3
  370.                      /* now_col > adj_max_col - 2 && !ps.box_com */ )
  371.                 {
  372.                     *e_com = '\0';
  373.                     dump_line();
  374.                     now_col = ps.com_col;
  375.                 }
  376.                 check_size(com);
  377.                 *e_com++ = '*';
  378.                 *e_com++ = '/';
  379.                 *e_com = '\0';
  380.                 ps.just_saw_decl = l_just_saw_decl;
  381.                 return;
  382.             }
  383.             else
  384.             {                   /* handle isolated '*' */
  385.                 *e_com++ = '*';
  386.                 ++now_col;
  387.             }
  388.             break;
  389.         default:               /* we have a random char */
  390.             if (unix_comment == 0 && *buf_ptr != ' ' && *buf_ptr != '\t')
  391.                 unix_comment = 1; /* we are not in unix-style comment */
  392.  
  393.             *e_com = *buf_ptr++;
  394.             if (buf_ptr >= buf_end)
  395.                 fill_buffer();
  396.  
  397.             if (*e_com == '\t') /* keep track of column */
  398.                 now_col = now_col + (tabsize - ((now_col - 1) % tabsize));
  399.             else if (*e_com == '\b')  /* this is a backspace */
  400.                 --now_col;
  401.             else
  402.                 ++now_col;
  403.  
  404.             if (*e_com == ' ' || *e_com == '\t')
  405.                 last_bl = e_com;
  406.             /* remember we saw a blank */
  407.  
  408.             ++e_com;
  409.             if (now_col > adj_max_col && !ps.box_com && unix_comment == 1 && e_com[-1] > ' ')
  410.             {
  411.                 /*
  412.                    the comment is too long, it must be broken up
  413.                 */
  414.                 if (break_delim == 1 && s_com[0] == '/'
  415.                     && s_com[1] == '*' && s_com[2] == ' ')
  416.                 {
  417.                     char *t = e_com;
  418.  
  419.                     break_delim = 2;
  420.                     e_com = s_com + 2;
  421.                     *e_com = 0;
  422.                     if (blanklines_before_blockcomments)
  423.                         prefix_blankline_requested = 1;
  424.                     dump_line();
  425.                     e_com = t;
  426.                     s_com[0] = s_com[1] = s_com[2] = ' ';
  427.                 }
  428.                 if (last_bl == 0)
  429.                 {               /* we have seen no blanks */
  430.                     last_bl = e_com;  /* fake it */
  431.                     *e_com++ = ' ';
  432.                 }
  433.                 *e_com = '\0';  /* print what we have */
  434.                 *last_bl = '\0';
  435.                 while (last_bl > s_com && last_bl[-1] < 040)
  436.                     *--last_bl = 0;
  437.                 e_com = last_bl;
  438.                 dump_line();
  439.  
  440.                 *e_com++ = ps.cc_comment ? '/' : ' '; /* blanks or slashes */
  441.                 *e_com++ = ps.cc_comment ? '/' : ' '; /* for continuation */
  442.                 *e_com++ = ' ';
  443.  
  444.                 t_ptr = last_bl + 1;
  445.                 last_bl = 0;
  446.                 if (t_ptr >= e_com)
  447.                 {
  448.                     while (*t_ptr == ' ' || *t_ptr == '\t')
  449.                         t_ptr++;
  450.                     while (*t_ptr != '\0')
  451.                     {           /* move unprinted part of comment down in
  452.                                    buffer */
  453.                         if (*t_ptr == ' ' || *t_ptr == '\t')
  454.                             last_bl = e_com;
  455.                         *e_com++ = *t_ptr++;
  456.                     }
  457.                 }
  458.                 *e_com = '\0';
  459.                 now_col = count_spaces(ps.com_col, s_com);  /* recompute current
  460.                                                                position */
  461.             }
  462.             break;
  463.         }
  464.     }
  465. }
  466.